package com.qfedu.bookstores.dao;

import com.qfedu.bookstores.util.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

//这个类是专门用来让其他dao层类继承 ,dao层通用逻辑的实现
public abstract class BaseDao {
    //1.提供工具类DBUtils的QueryRunner对象
    private QueryRunner queryRunner = new QueryRunner();

    /**
     * 提供通用方法叫做update -->可以执行 insert、update 和delete
     * @param sql 提供insert、update和delete的sql语句
     * @param args 语句中更需要使用到参数
     * @return 返回-1 证明操作失败 否则成功
     */
    public int update(String sql,Object... args){
        Connection connection = JDBCUtils.getConnection();
        //方法内部最终还是要调用DBUtils工具类所以需要对方法设置参数以便可以
        //传递到DBUtils方法中使用
        try {
            return  queryRunner.update(connection,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(connection);
        }
        return  -1;
    }

    /**
     * 查询一个数据并封装到实体类对象中
     * @param sql  查询语句
     * @param args 查询语句中所使用参数
     * @param <T>  参数中泛型起到作用就是决定这个方法查询出的Bean的数据类型
     * @return  null 没有查询到结果 否则返回查询到实体类对象
     */
    public<T> T queryForOne(Class<T> type,String sql,Object...args){
        //1.获取连接对象
        Connection connection = JDBCUtils.getConnection();
        //2.调用DBUtils工具类中查询方法
        try {
            return queryRunner.query(connection, sql,
                    new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(connection);
        }
        return null;
    }

    /**
     * 查询表中的多个结果集并封装到List集合中
     * @param type 要返回的实体类类型
     * @param sql  查询语句
     * @param args 查询语句中参数
     * @param <T>  数中泛型起到作用就是决定这个方法查询出的Bean的数据类型
     * @return null 没有到结果  否则返回存储着实体类结果集的List集合对象
     */
    public<T> List<T> queryForList(Class<T> type,String sql,Object... args){
        Connection connection = JDBCUtils.getConnection();
        try {
            return queryRunner.query(connection, sql,
                    new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(connection);
        }
        return null;
    }

    /**
     * 聚合函数查询之后的结果
     * @param sql  查询语句
     * @param args  查询语句参数
     * @return 结果值
     */
    public Object queryForSingValue(String sql,Object... args){
        Connection connection = JDBCUtils.getConnection();
        try {
            return queryRunner.query(connection, sql,new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}
